﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class IServiceCollectionExtensions
    {
        public static void RegisterSingleton<TFac>(this IServiceCollection services, string assemName)
        {
            var assem = Assembly.Load(assemName);
            services.RegisterSingleton<TFac>(assem);
        }

        public static void RegisterSingleton<TFac>(this IServiceCollection services, Assembly assem)
        {
            services.Register<TFac>(assem, ServiceLifetime.Singleton);
        }

        public static void RegisterTransient<TFac>(this IServiceCollection services, string assemName)
        {
            var assem = Assembly.Load(assemName);
            services.RegisterTransient<TFac>(assem);
        }
        public static void RegisterTransient<TFac>(this IServiceCollection services, Assembly assem)
        {
            services.Register<TFac>(assem, ServiceLifetime.Transient);
        }
        public static void RegisterScoped<TFac>(this IServiceCollection services, string assemName)
        {
            var assem = Assembly.Load(assemName);
            services.RegisterScoped<TFac>(assem);
        }

        public static void RegisterScoped<TFac>(this IServiceCollection services, Assembly assem)
        {
            services.Register<TFac>(assem, ServiceLifetime.Scoped);
        }
        public static void Register<TFac>(this IServiceCollection services, Assembly assembly, ServiceLifetime serviceLifeTimeEnum)
        {
            var assemTypes = assembly.GetTypes().Where(e => e.IsAbstract == false && typeof(TFac).IsAssignableFrom(e));
            foreach (var item in assemTypes)
            {
                foreach (var inface in item.GetInterfaces().Where(e => e.Name != typeof(TFac).Name))
                {
                    switch (serviceLifeTimeEnum)
                    {
                        case ServiceLifetime.Singleton:
                            services.AddSingleton(inface, item);
                            break;
                        case ServiceLifetime.Scoped:
                            services.AddScoped(inface, item);
                            break;
                        case ServiceLifetime.Transient:
                            services.AddTransient(inface, item);
                            break;
                        default:
                            throw new ArgumentException($"{serviceLifeTimeEnum} not found.");
                    }
                }
            }
        }

    }
}
